/* File: Text.m - (Interactive) Unix shell version of Text
 *
 * By: Gerben Wierda (gerben@rna.indiv.nluug.nl)
 * As inspired by Christopher Lane (lane@sumex-aim.stanford.edu)
 *
 * Date: 2 may 1993
 *
 * Copyright: 1993 by R&A
 *
 * This program may be distributed without restriction.
 */

// A very long line to see if everyhting is displayed OK. A very long line to see if everyhting is displayed OK. A very long line to see if everyhting is displayed OK.

#import <stdlib.h>
#import "getopt.h"

#import <appkit/appkit.h>

#define SELECTOR @selector(stop:)
#define TIMEOUT (30)

#define DEFAULTWIDTH	400.0
#define DEFAULTHEIGHT	400.0
#define DEFAULTX	150.0
#define DEFAULTY	750.0

#define USAGE "usage: %s [-t title] [-x xpos -y ypos] [-T seconds] [file]\n"
#define EXIT_USAGE (2)

@interface TextApp : Application
{
    id window;
    int startcount;
}

- initWindow;
- appDidInit:sender;

@end

@implementation TextApp : Application

- initWindow
{
    NXRect windowrect;

    NXSetRect( &windowrect, DEFAULTX, DEFAULTY,
	       DEFAULTWIDTH, DEFAULTHEIGHT);
    window = [[Window alloc]
	      initContent:  &windowrect
	      style:	    NX_RESIZEBARSTYLE
	      backing:	    NX_BUFFERED
	      buttonMask:   NX_CLOSEBUTTONMASK
	      defer:	    NO];
    [window setContentView:[[ScrollView alloc] initFrame:&windowrect]];
    [[window contentView] setDocView:[[Text alloc] initFrame:&windowrect]];

    return window;
}

- appDidInit:sender
{
    [[self appIcon] orderOut:self];

    return self;
}

@end

void timer(DPSTimedEntry teNumber, double now, int status) { exit(status); }

void main(int argc, char *argv[])
{
    BOOL orderFront = NO;
    const char *title = NULL;
    double timeout = TIMEOUT;
    int option, status = EXIT_SUCCESS;
    NXPoint topleft = { DEFAULTX, DEFAULTY };
    NXSize size = { DEFAULTWIDTH, DEFAULTHEIGHT };
    DPSTimedEntry teNumber = NULL;
    NXStream *stream = NULL;
    
    while ((option = getopt(argc, argv, "Fc:t:x:y:X:Y:T:")) != EOF)
    switch (option)
    {
    case 'F': orderFront = YES; break;
    case 't': title = optarg; break;
    case 'x': topleft.x = atof(optarg); break;
    case 'y': topleft.y = atof(optarg); break;
    case 'X': size.width = atof(optarg); break;
    case 'Y': size.height = atof(optarg); break;
    case 'T': timeout = atol(optarg); break;
    default : status = EXIT_USAGE;
    }
    
    NXApp = [TextApp new];

    if (status == EXIT_USAGE)
    {
	(void) fprintf(stderr, USAGE, [NXApp appName]);
    }
    else
    {
	float xdisplacement = 0.0;
	float ydisplacement = 0.0;
	
	for (; optind < argc; optind++)
	{
	    if (stream = (strcmp( argv[optind], "-") ?
			  NXMapFile( argv[optind], NX_READWRITE) :
			  NXOpenFile(fileno( stdin), NX_READONLY)))
	    {
		NXRect windowrect, textrect;
		id window;
		id scrollview;
		id text;

		window = [NXApp initWindow];
		[window setDelegate:NXApp];
		scrollview = [window contentView];
		text = [scrollview docView];
		
		[window setTitle:(title == NULL ?
				  (strcmp( argv[optind], "-") ?
				   argv[optind]: "<<stdin>>") :
				  title)];
		[window displayBorder];
		[window setBackgroundGray:NX_LTGRAY];

		[window sizeWindow:size.width :size.height];
		[window moveTopLeftTo:topleft.x :topleft.y];

		if (xdisplacement != 0.0 ||
		    ydisplacement != 0.0)
		{
		    [window getFrame:&windowrect];
		    windowrect.origin.x += xdisplacement;
		    windowrect.origin.y += ydisplacement;
		    [window moveTo:windowrect.origin.x :windowrect.origin.y];
		}
		xdisplacement += 18.0;
		ydisplacement -= 18.0;
		
		[scrollview setVertScrollerRequired:YES];
		[scrollview setHorizScrollerRequired:NO];
		[scrollview getContentSize:&textrect.size];

		[text setHorizResizable:NO];
		[text setVertResizable:YES];
		[text setMinSize:&textrect.size];
		[text sizeTo:textrect.size.width :textrect.size.height];
		[text setOpaque:YES];
		[text setEditable:NO];
		[text readText:stream];
		[text sizeToFit];

		if (orderFront)
		{
		    [window orderFrontRegardless];
		}
		else
		{
		    [window orderFront:nil];
		}
		[window display];

		NXClose( stream);
	    }
	}
	if (timeout)
	{
	    teNumber = DPSAddTimedEntry( timeout,
					 (DPSTimedEntryProc) &timer,
					 (void *) EXIT_FAILURE,
					 NX_BASETHRESHOLD);
	}

	[NXApp run];
	
	if(timeout) DPSRemoveTimedEntry(teNumber);
    }
    [NXApp free];

    exit(status);
}

@interface TextApp(WindowDelegate)
- windowWillClose:sender;
- windowDidResize:sender;
@end

@implementation TextApp(WindowDelegate)
- windowWillClose:sender
{
    if ([[NXApp windowList] count] <= 4)
    {
	[NXApp terminate:nil];
    }
    return self;
}
- windowDidResize:sender
{
    NXRect textrect;
    
    [[sender contentView] getContentSize:&textrect.size];

    [[[sender contentView] docView] setMinSize:&textrect.size];
    [[[sender contentView] docView]
     sizeTo:textrect.size.width :textrect.size.height];
    [[[sender contentView] docView] sizeToFit];

//    [sender display];
    return self;
}
@end

@interface TextApp(TextDelegate)
@end

@implementation TextApp(TextDelegate)
@end
